package cloud.lysky.java.on.concurrent.cas;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;
import java.util.concurrent.locks.LockSupport;

/**
 * @author luoly
 * @describe
 * @date 2022-10-21 22:52
 **/
public class AtomicStampedReferenceTest {
    public static void main(String[] args) {
        // 定义AtomicStampedReference Pair.reference值为1, Pair.stamp为1
        AtomicStampedReference atomicStampedReference = new AtomicStampedReference(1,1);

        //开启一个线程
        new Thread(() -> {
            //stampHolder用来接收stamp 即版本
            int[] stampHolder = new int[1];
            int value = (int) atomicStampedReference.get(stampHolder);
            int stamp = stampHolder[0];
            System.out.println("线程1读到的value值：" + value + ",stamp = " + stamp);
            //阻塞1秒
            LockSupport.parkNanos(1000000000L);
            //线程1通过CAS修改Value值为3
            if (atomicStampedReference.compareAndSet(value,3,stamp,stamp + 1)){
                System.out.println("线程1将value的值从" + value + "更新为3,版本stamp变成" + (stamp + 1 ));
            }else{
                System.out.println("线程1更新失败！");
            }
        },"线程1").start();

        //开启第二个线程将值改成2再改回1
        new Thread(()->{
            int[] stampHolder = new int[1];
            int value = (int) atomicStampedReference.get(stampHolder);
            int stamp = stampHolder[0];
            System.out.println("线程2读到的value值：" + value + ",stamp = " + stamp);
            //修改value的值为2
            if (atomicStampedReference.compareAndSet(value,2,stamp,stamp + 1)){
                System.out.println("线程2将value的值从" + value + "更新为2,版本stamp变成" + (stamp + 1 ));
            }

            value = (int) atomicStampedReference.get(stampHolder);
            stamp = stampHolder[0];
            System.out.println("线程2读到的value值：" + value + ",stamp = " + stamp);
            //再修改value的值为改回1
            if (atomicStampedReference.compareAndSet(value,1,stamp,stamp + 1)){
                System.out.println("线程2将value的值从" + value + "更新为1,版本stamp变成" + (stamp + 1 ));
            }
        },"线程2").start();
    }
}